﻿using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;

namespace QbservableCore.Serialization.Helpers
{
    /// <summary>
    /// Serializable helper for Field or Property
    /// </summary>
    [DataContract]
    public class SerializableMemberInfo
    {
        private readonly LightweightSerializableType _serializableDeclaringType;
        private readonly int _metadataCacheToken; 
        private readonly MemberType _type;

        public SerializableMemberInfo(MemberInfo member)
        {
            _serializableDeclaringType = new LightweightSerializableType(member.DeclaringType);
            _metadataCacheToken = member.MetadataToken;
            _type = member is FieldInfo ? MemberType.Field : MemberType.Property;
        }

        public MemberInfo Deserialize()
        {
            Type declaringType = _serializableDeclaringType.ToType();
            TypeInfo typeInfo = declaringType.GetTypeInfo();
            MemberInfo MemberInfo;
            if (_type == MemberType.Field)
            {
                if (typeInfo.IsGenericType)
                {
                    MemberInfo =
                        (from field in typeInfo.DeclaredFields
                         where field.MetadataToken == _metadataCacheToken
                         select field).First();
                }
                else
                {
                    MemberInfo = declaringType.Module.ResolveField(_metadataCacheToken);
                }
            }
            else // is property
            {
                MemberInfo =
                    (from property in typeInfo.DeclaredProperties
                     where property.MetadataToken == _metadataCacheToken
                     select property).First();
            }

            return MemberInfo;
        }
    }

}